﻿<template>
  <div v-loading="loading" class="module-content">
    <div class="region-main">
      <!-- 查询条件及按钮 -->
      <div class="funcButton">
        <el-input v-model="query" style="width:200px; margin-right:5px;" placeholder="关键字" maxlength="30" clearable></el-input>
        <el-button v-show="canShowBtn('pageList')" icon="el-icon-zoom-in" type="primary" @click="getList(true)">查询</el-button>
        <el-button v-show="canShowBtn('pageList')" type="primary" @click="searchWindowVisible=true">高级查询</el-button>
        <!-- 右侧功能按钮 -->
        <div class="btnRight">
          <el-button v-show="canShowBtn('add')" icon="el-icon-plus" type="primary" @click="onAdd()">添加</el-button>
          <el-button v-show="canShowBtn('del')" icon="el-icon-delete" type="danger" @click="onDel()">删除</el-button>
          <el-button v-show="canShowBtn('import')" icon="el-icon-upload2" type="success" @click="onImp()">导入</el-button>
          <el-button v-show="canShowBtn('export')" icon="el-icon-download" type="warning" @click="onExp()">导出</el-button>
          <el-button v-show="canShowBtn('export')" icon="el-icon-download" type="warning" @click="onExpRouterJson()">路由Json</el-button>
          <el-button v-show="canShowBtn('des')" type="danger" @click="onDel()">销毁</el-button>
          <el-button v-show="canShowBtn('res')" type="success" @click="onRes()">还原</el-button>
        </div>
        <!-- 过滤栏可多行 -->
        <div class="barFilter">
          <span class="title">子平台:</span>
          <el-radio-group v-model="platformId" @change="onChangePlatform">
            <!-- <el-radio :key="0" :label="0">全部</el-radio> -->
            <el-radio v-for="item in kvSysPlatform" :key="item.id" :label="item.id">{{ item.name }}</el-radio>
          </el-radio-group>
        </div>
      </div>
      <!-- 分页表格 -->
      <div class="datatable">
        <el-table
          ref="tableDom"
          :data="tableData"
          border
          style="width: 100%"
          row-key="id"
          lazy
          :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
          :load="loadChildrenNode"
          @row-click="onCellCancel"
          @selection-change="onMulSelect"
          @sort-change="onSortTable"
          @cell-dblclick="onCellEdit"
        >
          <el-table-column type="selection" width="45" fixed="left"></el-table-column>
          <!-- <el-table-column prop="id" label="编号" width="100" sortable="custom"></el-table-column> -->
          <el-table-column prop="name" label="模块名" min-width="180" sortable="custom" :show-overflow-tooltip="true"></el-table-column>
          <el-table-column prop="enName" label="英文名" min-width="180" sortable="custom" :show-overflow-tooltip="true"></el-table-column>
          <el-table-column prop="controllerName" label="控制器名" min-width="180" sortable="custom" :show-overflow-tooltip="true"></el-table-column>
          <!-- <el-table-column prop="parentId" label="父模块id" min-width="109" sortable="custom" :show-overflow-tooltip="true"></el-table-column> -->
          <el-table-column prop="routerPath" label="前端路由" min-width="200" sortable="custom" :show-overflow-tooltip="true"></el-table-column>
          <el-table-column prop="icon" label="模块图标" min-width="110" sortable="custom" :show-overflow-tooltip="true"></el-table-column>
          <el-table-column prop="platformId" label="所属平台" min-width="124" sortable="custom" :show-overflow-tooltip="true">
            <template slot-scope="scope">{{ scope.row.platformId|filterId2Name(kvSysPlatform) }}</template>
          </el-table-column>
          <!-- <el-table-column prop="meta" label="前端模块和路由中的meta" min-width="223" sortable="custom" :show-overflow-tooltip="true" /> -->
          <!-- <el-table-column prop="redirect" label="重定向" min-width="95" sortable="custom" :show-overflow-tooltip="true" /> -->
          <el-table-column prop="hidden" label="菜单隐藏" min-width="121" :show-overflow-tooltip="true">
            <template slot-scope="scope">
              <el-switch v-model="scope.row.hidden" :disabled="!canShowBtn('mod')" @change="onRowMod(scope.row,{ hidden: scope.row.hidden })">
              </el-switch>
            </template>
          </el-table-column>
          <el-table-column prop="loginVerify" label="登录验证" min-width="80" :show-overflow-tooltip="true">
            <template slot-scope="scope">
              <el-switch v-model="scope.row.loginVerify" :disabled="!canShowBtn('mod')" @change="onRowMod(scope.row,{ loginVerify: scope.row.loginVerify })"></el-switch>
            </template>
          </el-table-column>
          <el-table-column prop="actionVerify" label="动作验证" min-width="80" :show-overflow-tooltip="true">
            <template slot-scope="scope">
              <el-switch v-model="scope.row.actionVerify" :disabled="!canShowBtn('mod')" @change="onRowMod(scope.row,{ actionVerify: scope.row.actionVerify })"></el-switch>
            </template>
          </el-table-column>
          <!-- <el-table-column prop="component" label="前端模块和路由中的component获取方式" min-width="330" sortable="custom" :show-overflow-tooltip="true" /> -->
          <el-table-column prop="sortNo" label="排序码" min-width="95" sortable="custom" :show-overflow-tooltip="true">
            <template slot-scope="scope">
              <span v-if="scope.row.id == cellId && cellKey == 'sortNo'">
                <el-popconfirm title="是否确认修改？" @onConfirm="onCellMod(scope.row)" @onCancel="onCellCancel">
                  <el-input slot="reference" v-model="cellVal" size="small"></el-input>
                </el-popconfirm>
              </span>
              <span v-if="scope.row.id !== cellId || cellKey !== 'sortNo'">{{ scope.row.sortNo }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="description" label="描述" min-width="80" sortable="custom" :show-overflow-tooltip="true"></el-table-column>
          <el-table-column prop="valid" label="是否有效" min-width="80" fixed="right" :show-overflow-tooltip="true">
            <template slot-scope="scope">
              <el-switch v-model="scope.row.valid" :disabled="!canShowBtn('mod')" @change="onRowMod(scope.row,{ valid: scope.row.valid })">
              </el-switch>
            </template>
          </el-table-column>
          <el-table-column prop="createrName" label="创建人" min-width="110" sortable="custom" :show-overflow-tooltip="true"></el-table-column>
          <el-table-column prop="createTime" label="创建时间" min-width="160" sortable="custom" :show-overflow-tooltip="true"></el-table-column>
          <el-table-column prop="updateTime" label="修改时间" min-width="160" sortable="custom" :show-overflow-tooltip="true"></el-table-column>
          <el-table-column prop="deleteTime" label="删除时间" min-width="160" sortable="custom" :show-overflow-tooltip="true"></el-table-column>

          <el-table-column fixed="right" label="操作" width="160">
            <template slot-scope="scope">
              <el-button v-show="canShowBtn('det')" size="small" type="text" @click="onView(scope.row)">查看</el-button>
              <el-button v-show="canShowBtn('add')" size="small" type="text" @click="onAdd(scope.row)">添加</el-button>
              <el-button v-show="canShowBtn('mod')" size="small" type="text" @click="onMod(scope.row)">编辑</el-button>
              <el-button v-show="canShowBtn('del')" size="small" type="text" @click="onDel(scope.row)">删除</el-button>
              <el-button v-show="canShowBtn('des')" size="small" type="text" @click="onDel(scope.row)">销毁</el-button>
              <el-button v-show="canShowBtn('res')" size="small" type="text" @click="onRes(scope.row)">还原</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <!-- 分页组件 -->
      <div class="pagination">
        <el-checkbox v-if="(btnApiAuth.des && btnApiAuth.des.result)||(btnApiAuth.res && btnApiAuth.res.result)" v-model="recMode" title="切换显示已删除的数据">
          已删除</el-checkbox>
        <el-checkbox v-model="showPageTotal" title="显示统计总数据量，数据量大时等待时间会较长">总数</el-checkbox>
        <el-pagination
          background
          :current-page="currPage"
          :page-size="pageSize"
          :total="pageTotal"
          :page-sizes="[10, 20, 30, 40, 50, 100]"
          layout="prev,pager,next,jumper,sizes,total"
          @size-change="onPageSizeChange"
          @current-change="onCurrPageChange"
        ></el-pagination>
      </div>
      <!-- 添加编辑 -->
      <div class="addFrmDialog">
        <el-dialog :title="formOp" :visible.sync="dfvAddEdit" :close-on-click-modal="false" :modal-append-to-body="false" top="7vh" width="55%" @close="onFormClose('formModel')">
          <el-alert title="注意：如果添加模块组不需要填控制器名、视图路径，模块组最好添加图标！" type="info" :closable="false" class="mb-2" show-icon style="margin-bottom:20px">
          </el-alert>
          <el-form ref="formModel" v-loading="loadingForm" :model="formModel" :rules="rules">
            <el-row :gutter="addgutterSize">
              <el-col :xs="addxsSize" :sm="addsmSize" :md="addmdSize" :lg="addlgSize" :xl="addxlSize">
                <el-form-item prop="platformId" label="所属平台" :label-width="lblWidth">
                  <!-- <el-input-number v-model="formModel.platformId" :min="0" :max="2147483647" placeholder="请输入所属平台id" /> -->
                  <el-select v-model="formModel.platformId" filterable placeholder="请选择" @change="onfChangePlatform">
                    <el-option v-for="item in kvSysPlatform" :key="item.id" :label="item.name" :value="item.id"></el-option>
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :xs="addxsSize" :sm="addsmSize" :md="addmdSize" :lg="addlgSize" :xl="addxlSize">
                <el-form-item prop="parentId" label="父模块" :label-width="lblWidth">
                  <el-select v-model="formModel.parentId" filterable placeholder="请选择">
                    <el-option v-for="item in kvSysModule" :key="item.id" :label="item.name" :value="item.id"></el-option>
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :xs="addxsSize" :sm="addsmSize" :md="addmdSize" :lg="addlgSize" :xl="addxlSize">
                <el-form-item prop="name" label="模块名" :label-width="lblWidth">
                  <el-input v-model="formModel.name" auto-complete="off" clearable maxlength="20" show-word-limit placeholder="请输入模块名"></el-input>
                </el-form-item>
              </el-col>
              <el-col :xs="addxsSize" :sm="addsmSize" :md="addmdSize" :lg="addlgSize" :xl="addxlSize">
                <el-form-item prop="enName" label="英文名" :label-width="lblWidth" title="项目内唯一 主要用于路由中name和meta中title(首字母转小写)给前端做语言切换标识 格式如AdminUserName建议使用平台名简称+后台控制器名">
                  <el-input v-model="formModel.enName" auto-complete="off" clearable maxlength="200" show-word-limit placeholder="如AdminUserName"></el-input>
                </el-form-item>
              </el-col>
              <el-col :xs="addxsSize" :sm="addsmSize" :md="addmdSize" :lg="addlgSize" :xl="addxlSize">
                <el-form-item prop="controllerName" label="控制器名" :label-width="lblWidth" title="平台内唯一 主要用于同步接口时关联后台接口 格式如UserName">
                  <el-input v-model="formModel.controllerName" auto-complete="off" clearable maxlength="200" show-word-limit placeholder="如UserName 后台控制器名" @change="onSetRouterPath"></el-input>
                </el-form-item>
              </el-col>
              <el-col :xs="addxsSize" :sm="addsmSize" :md="addmdSize" :lg="addlgSize" :xl="addxlSize">
                <el-form-item prop="routerPath" label="前端路由" :label-width="lblWidth" title="前端访问路由\平台\模块组拼接 如userName">
                  <el-input v-model="formModel.routerPath" auto-complete="off" clearable maxlength="200" show-word-limit placeholder="如userName 前端访问路由\平台\模块组拼接"></el-input>
                </el-form-item>
              </el-col>
              <el-col :xs="addxsSize" :sm="addsmSize" :md="addmdSize" :lg="addlgSize" :xl="addxlSize">
                <el-form-item prop="icon" label="模块图标" :label-width="lblWidth" title="图标码">
                  <el-input v-model="formModel.icon" auto-complete="off" clearable maxlength="200" show-word-limit placeholder="element_ui图标"></el-input>
                </el-form-item>
              </el-col>
              <!-- <el-col :xs="addxsSize" :sm="addsmSize" :md="addmdSize" :lg="addlgSize" :xl="addxlSize">
                <el-form-item prop="redirect" label="重定向" :label-width="lblWidth">
                  <el-input v-model="formModel.redirect" auto-complete="off" clearable maxlength="200" show-word-limit placeholder="请输入重定向" />
                </el-form-item>
              </el-col> -->
            </el-row>
            <el-row>
              <el-col :xs="addxsSize" :sm="addsmSize" :md="addmdSize" :lg="addlgSize" :xl="addxlSize">
                <el-form-item prop="loginVerify" label="登录验证" :label-width="lblWidth" title="对前端页面做访问权限限制">
                  <el-switch v-model="formModel.loginVerify"></el-switch>
                </el-form-item>
              </el-col>
              <el-col :xs="addxsSize" :sm="addsmSize" :md="addmdSize" :lg="addlgSize" :xl="addxlSize">
                <el-form-item prop="actionVerify" label="权限验证" :label-width="lblWidth" title="对前端页面做访问权限限制">
                  <el-switch v-model="formModel.actionVerify"></el-switch>
                </el-form-item>
              </el-col>
              <el-col :xs="addxsSize" :sm="addsmSize" :md="addmdSize" :lg="addlgSize" :xl="addxlSize">
                <el-form-item prop="hidden" label="菜单隐藏" :label-width="lblWidth" title="对左侧菜单模块显示限制">
                  <el-switch v-model="formModel.hidden"></el-switch>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :xs="addxsSize" :sm="addsmSize" :md="addmdSize" :lg="addlgSize" :xl="addxlSize">
                <el-form-item prop="component" label="视图路径" :label-width="lblWidth" title="获取组件的code 如() => import('@/views/appAdmin/sysManage/sysModule') 不填则在导出路由时程序自动生成">
                  <el-input v-model="formModel.component" type="textarea" :rows="4" auto-complete="off" maxlength="400" show-word-limit placeholder="获取前端视图component:代码 不填则在导出路由时程序自动生成"></el-input>
                </el-form-item>
              </el-col>
              <el-col :xs="addxsSize" :sm="addsmSize" :md="addmdSize" :lg="addlgSize" :xl="addxlSize">
                <el-form-item prop="sortNo" label="排序码" :label-width="lblWidth">
                  <el-input-number v-model="formModel.sortNo" :min="0" :max="2147483647" placeholder="请输入排序码"></el-input-number>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :xs="addxsSize" :sm="addsmSize" :md="addmdSize" :lg="addlgSize" :xl="addxlSize">
                <el-form-item prop="meta" label="路由meta" :label-width="lblWidth" title="title为菜单显示的文本 多语言关联此字段">
                  <el-input v-model="formModel.meta" type="textarea" :rows="4" auto-complete="off" maxlength="2000" show-word-limit placeholder="路由meta:代码 不填则由程序自动生成"></el-input>
                </el-form-item>
              </el-col>
              <!-- <el-col :xs="addxsSize" :sm="addsmSize" :md="addmdSize" :lg="addlgSize" :xl="addxlSize">
                <el-form-item prop="routerJson" label="路由json" :label-width="lblWidth">
                  <el-input v-model="formModel.routerJson" type="textarea" :rows="4" auto-complete="off" maxlength="2000" show-word-limit placeholder="请生成路由json" />
                </el-form-item>
              </el-col> -->
              <el-col :xs="addxsSize" :sm="addsmSize" :md="addmdSize" :lg="addlgSize" :xl="addxlSize">
                <el-form-item prop="description" label="描述" :label-width="lblWidth">
                  <el-input v-model="formModel.description" type="textarea" :rows="4" auto-complete="off" maxlength="2000" show-word-limit placeholder="请输入描述"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
          </el-form>
          <div v-show="!loadingForm" slot="footer" class="dialog-footer">
            <el-button @click="onCreateMeta">生成meta</el-button>
            <!-- <el-button @click="onCreateRouter">生成路由</el-button> -->
            <el-button @click="dfvAddEdit = false">取 消</el-button>
            <el-button v-show="formOp!=='查看'&&formOp!=='编辑'" type="primary" @click="addOrMod('formModel', true)">保 存</el-button>
            <el-button v-show="formOp!=='查看'" type="primary" @click="addOrMod('formModel')">确 定</el-button>
          </div>
        </el-dialog>
      </div>
      <!-- 导入excel -->
      <div class="impFrmDialog">
        <el-dialog :title="'导入Excel'" :visible.sync="dfvExcelImport" top="7vh" width="500px">
          <excel-import tip="只能上传xls/xlsx文件，且不超过4MB" :form-max-size="4" :param="importParam" :file-type="importType" :import-api="importApi" :template-url="templateUrl" @success="getList">
          </excel-import>
        </el-dialog>
      </div>
      <!-- 导出excel -->
      <div class="expFrmDialog">
        <el-dialog :title="'导出excel'" :visible.sync="dfvExcelExport" top="7vh" width="800px">
          <excel-export :page-dto="pageDto" :export-api="exportApi" :export-fields="exportFields" @close="dfvExcelExport=false"></excel-export>
        </el-dialog>
      </div>
      <!--高级查询窗口-->
      <search-window :visible.sync="searchWindowVisible" :fields="filterFields" @click="onSearchFilter"></search-window>
    </div>
  </div>
</template>

<script>
// import { mapState } from 'vuex'
import * as common from '@/utils/common'
import * as baseApi from '@/api'
import * as platformApi from '@/api/appAdmin'
import { Loading } from 'element-ui'
// import * as formValidate from '@/utils/formValidate'

export default {
  name: 'SysModule',
  components: {
    // 引用组件
  },
  data() {
    // 通用验证方法
    // var validate = formValidate
    return {
      // 等待状态
      loading: false,
      loadingForm: false,
      // 搜索输入
      query: '',
      // 回收站开关
      recMode: false,
      // 选中的行
      selectRows: [],
      // 排序的列
      sortCol: '',
      // 最后一次分页参数
      pageDto: {},
      // 当前页码
      currPage: 1,
      // 页尺寸
      pageSize: 20,
      // 页总记录数
      pageTotal: 1,
      // 显示总记录数
      showPageTotal: false,
      // 表格数据
      tableData: [],
      // 弹窗输入框label宽度
      lblWidth: '120px',
      // 表单数据模型
      formModel: {},
      // 表单添加or编辑or查看
      formOp: '',
      // 显示添加编辑
      dfvAddEdit: false,
      // 显示excel导入
      dfvExcelImport: false,
      // 显示excel导出
      dfvExcelExport: false,
      // 上传文件get参数
      importParam: {},
      // 上传文件类型
      importType: ['xlsx', 'xls'],
      // 模板url
      templateUrl: process.env.VUE_APP_UPLOAD_FILE_API + '/fileSite/excel/template/Import<#tableName#>.xlsx',
      // 导入excel接口
      importApi: '',
      // 导出excel接口
      exportApi: '',
      // 导出字段
      exportFields: [
        { value: 'Id', label: '编号' },
        { value: 'Name', label: '模块名' },
        { value: 'EnName', label: '英文名' },
        { value: 'ControllerName', label: '控制器名' },
        { value: 'ParentId', label: '父模块id' },
        { value: 'RouterPath', label: '前端页面访问路由' },
        { value: 'Icon', label: '模块图标' },
        { value: 'PlatformId', label: '所属平台id' },
        { value: 'Meta', label: '前端模块和路由中的meta' },
        // { value: 'Redirect', label: '重定向' },
        { value: 'Hidden', label: '是否在菜单隐藏' },
        { value: 'LoginVerify', label: '登录验证' },
        { value: 'actionVerify', label: '动作验证' },
        { value: 'Component', label: '前端模块和路由中的component获取方式' },
        { value: 'SortNo', label: '排序码' },
        { value: 'Description', label: '描述' },
        { value: 'Valid', label: '是否有效' },
        { value: 'CreaterName', label: '创建人' },
        { value: 'CreateTime', label: '创建时间' },
        { value: 'UpdateTime', label: '修改时间' },
        { value: 'DeleteTime', label: '删除时间' }
      ],
      // 高级查询字段
      filterFields: [
        { value: 'Id', label: '编号', type: 'number' },
        { value: 'Name', label: '模块名', type: 'string' },
        { value: 'EnName', label: '英文名', type: 'string' },
        { value: 'ControllerName', label: '控制器名', type: 'string' },
        { value: 'ParentId', label: '父模块id', type: 'number' },
        { value: 'RouterPath', label: '前端页面访问路由', type: 'string' },
        { value: 'Icon', label: '模块图标', type: 'string' },
        { value: 'PlatformId', label: '所属平台id', type: 'number' },
        { value: 'Meta', label: '前端模块和路由中的meta', type: 'string' },
        // { value: 'Redirect', label: '重定向', type: 'string' },
        { value: 'Hidden', label: '是否在菜单隐藏', type: 'bool' },
        { value: 'LoginVerify', label: '登录验证', type: 'bool' },
        { value: 'actionVerify', label: '动作验证', type: 'bool' },
        {
          value: 'Component',
          label: '前端模块和路由中的component获取方式',
          type: 'string'
        },
        { value: 'SortNo', label: '排序码', type: 'number' },
        { value: 'Description', label: '描述', type: 'string' },
        { value: 'Valid', label: '是否有效', type: 'bool' },
        { value: 'CreaterName', label: '创建人', type: 'string' },
        { value: 'CreateTime', label: '创建时间', type: 'date' },
        { value: 'UpdateTime', label: '修改时间', type: 'date' },
        { value: 'DeleteTime', label: '删除时间', type: 'date' }
      ],
      searchWindowVisible: false,
      // 表格编辑
      cellId: 0,
      cellKey: null,
      cellVal: null,
      // 添加编辑框响应式数据
      addgutterSize: 0,
      addxsSize: 24,
      addsmSize: 24,
      addmdSize: 12,
      addlgSize: 12,
      addxlSize: 12,
      // 表单验证
      rules: {
        name: [{ required: true, message: '请输入模块名', trigger: 'blur' }],
        enName: [{ required: true, message: '请输入英文名', trigger: 'blur' }],
        routerPath: [{ required: true, message: '请输入前端路由', trigger: 'blur' }]
      },
      // 按钮接口权限 参数api接口名 result权限验证结果 recShow为true回收站模式显示 norShow为true正常模式显示
      btnApiAuth: {
        pageList: { api: platformApi.sysModulePageList, result: false, recShow: true, norShow: true },
        export: { api: platformApi.sysModuleExportExcel, result: false, norShow: true },
        import: { api: platformApi.sysModuleImportExcel, result: false, norShow: true },
        add: { api: platformApi.sysModuleAdd, result: false, norShow: true },
        del: { api: platformApi.sysModuleDelete, result: false, norShow: true },
        des: { api: platformApi.sysModuleDestory, result: false, recShow: true, norShow: false },
        res: { api: platformApi.sysModuleRestore, result: false, recShow: true, norShow: false },
        mod: { api: platformApi.sysModuleModify, result: false, norShow: true },
        det: { api: platformApi.sysModuleDetail, result: false, recShow: true, norShow: true },
        downloadRouterJson: { api: platformApi.sysModuleGetRouterJson, result: false, recShow: false, norShow: true }
      },

      // 子系统信息
      kvSysPlatform: [],
      // 下拉模块信息
      kvSysModule: [],
      // 过滤栏子平台id
      platformId: 0,

      // 存储父子模块 父模块id -> { tree: row, treeNode, resolve }
      loadNodeMap: new Map(),
      // 编辑时父模块修改前的id 修改后需要刷新旧的父模块
      editParentId: 0
    }
  },
  computed: {
    // ...mapState(['user'])
  },
  watch: {
    recMode(val, oldVal) {
      this.getList(true)
    },
    showPageTotal(val, oldVal) {
      this.getList(true)
    }
  },
  created() {
    // console.log('SysModule created')
  },
  async mounted() {
    // console.log(this.user)
    this.pageSize = this.$store.getters.defPageSize
    await baseApi.verifyApiAuth(this.btnApiAuth)
    await this.getKVSysPlatform()
    await this.getList(true)
  },
  methods: {
    onSetRouterPath() {
      this.formModel.routerPath = common.toCamel(this.formModel.controllerName)
    },
    async onExpRouterJson() {
      if (!this.platformId) {
        this.$message({ type: 'error', message: '请选择子平台' })
        return
      }
      var loading = Loading.service({
        // target: document.getElementById('#app')
        fullscreen: true,
        text: '正在生成路由json，请稍后...'
      })

      await this.btnApiAuth.downloadRouterJson.api({ pId: this.platformId }, this, null, 1)
      // console.log(resp)

      loading.close()
    },
    // 弹窗切换平台
    onfChangePlatform(pId) {
      this.getKVSysModule(pId)
    },
    // 过滤切换平台
    onChangePlatform(pId) {
      this.getList(true)
    },
    // SysPlatform键值对
    async getKVSysPlatform() {
      const res = await platformApi.kvSysPlatform(null, this)
      if (res.ok) {
        this.kvSysPlatform = res.body
        this.kvSysPlatform = common.pushTop4Array(res.body, {
          id: 0,
          name: '全部'
        })
      }
    },
    // SysModule键值对
    async getKVSysModule(pId) {
      const param = { pId: this.$store.getters.currPlatformId, isParent: false }
      if (pId) {
        param.pId = pId
      }
      const res = await platformApi.kvSysModule(param, this)
      if (res.ok) {
        this.kvSysModule = common.pushTop4Array(res.body, {
          id: 0,
          name: '根节点'
        })
      }
    },
    onCreateMeta() {
      this.$refs['formModel'].validate(async valid => {
        if (valid) {
          // console.log(this.formModel.enName)
          this.formModel.meta = JSON.stringify({
            title: !this.formModel.enName ? '' : common.toCamel(this.formModel.enName),
            icon: !this.formModel.icon ? '' : this.formModel.icon,
            validLogin: !this.formModel.loginVerify ? false : this.formModel.loginVerify,
            validAction: !this.formModel.actionVerify ? false : this.formModel.actionVerify
          })
        }
      })
    },
    onCreateRouter() {
      // this.formModel.routerJson = '1234'
      this.$refs['formModel'].validate(async valid => {
        if (valid) {
          // console.log(this.formModel.actionVerify)
          this.formModel.routerJson = JSON.stringify({
            path: this.formModel.routerPath,
            name: this.formModel.enName,
            component: this.formModel.component,
            meta: {
              title: !this.formModel.enName ? '' : this.formModel.enName,
              icon: !this.formModel.icon ? '' : this.formModel.icon,
              validLogin: !this.formModel.loginVerify ? false : this.formModel.loginVerify,
              validAction: !this.formModel.actionVerify ? false : this.formModel.actionVerify
            }
          })
        }
      })
    },
    // 导出
    async onExp() {
      try {
        this.exportApi = await this.btnApiAuth.export.api(null, null, null, 5)
        this.dfvExcelExport = true
      } catch (error) {
        console.log(error)
      }
    },
    // 导入
    async onImp() {
      this.importApi = await this.btnApiAuth.import.api(null, null, null, 5)
      this.dfvExcelImport = true
    },
    // 添加
    onAdd(row) {
      this.formOp = '添加'
      // 注意formModel如果有字段需要传入组件 或字段是数组 要在赋值前声明到{}
      this.formModel = {
        meta: '',
        icon: '',
        enName: '',
        // component: `() => import('@/views/directory/directory/file')`,
        component: '',
        routerJson: '',
        routerPath: '',
        loginVerify: false,
        actionVerify: false
      }
      if (row) {
        this.onfChangePlatform(row.platformId)
        this.formModel.parentId = row.id
        this.formModel.platformId = row.platformId
      }
      this.dfvAddEdit = true
    },
    // 删除
    async onDel(row) {
      // 处理删除id
      const param = {}
      if (row) {
        param.ids = [row.id]
      } else {
        if (this.selectRows.length === 0) {
          this.$message({ type: 'error', message: '请至少选中一项' })
          return
        }
        param.ids = common.getId4ArrayObj(this.selectRows, 'id')
      }
      this.$confirm(
        this.recMode
          ? '此操作将销毁' + param.ids.length + '条记录且无法恢复！'
          : '确认删除' + param.ids.length + '条记录吗?',
        this.recMode ? '警告' : '提示',
        { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }
      )
        .then(async() => {
          // 处理真假删除
          var api = null
          if (this.recMode) {
            api = this.btnApiAuth.des.api
          } else {
            api = this.btnApiAuth.del.api
          }
          const res = await api(param, this, 'loading')
          if (res.ok) {
            this.$message({ type: 'success', message: '成功' + (this.recMode ? '销毁' : '删除') + res.body.count + '条数据' })
            // 更新子节点
            if (row.parentId) {
              // eslint-disable-next-line no-unused-vars
              const { tree, treeNode, resolve } = this.loadNodeMap.get(row.parentId)
              if (tree.id) {
                // 移除所有子节点并重读
                // console.log(this.$refs.tableDom.store.states.lazyTreeNodeMap)
                // this.$set(this.$refs.tableDom.store.states.lazyTreeNodeMap, tree.id, [])
                this.loadChildrenNode(tree, treeNode, resolve)
              }
            } else {
              // 根节点直接更新列表
              this.getList()
            }
          }
        })
        .catch(() => {})
    },
    // 还原
    async onRes(row) {
      // 处理还原id
      const param = {}
      if (row) {
        param.ids = [row.id]
      } else {
        if (this.selectRows.length === 0) {
          this.$message({ type: 'error', message: '请至少选中一项' })
          return
        }
        param.ids = common.getId4ArrayObj(this.selectRows, 'id')
      }
      this.$confirm('确认还原' + param.ids.length + '条记录吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(async() => {
          const res = await this.btnApiAuth.res.api(param, this, 'loading')
          if (res.ok) {
            this.$message({
              type: 'success',
              message: '成功还原' + res.body.count + '条数据'
            })
            this.getList()
          }
        })
        .catch(() => {})
    },
    // 编辑
    async onMod(row) {
      const param = { id: row.id }
      const res = await this.btnApiAuth.det.api(param, this, 'loading')
      if (res.ok) {
        res.body.routerJson = ''
        // console.log(res.body.routerJson)
        this.formOp = '编辑'
        this.formModel = res.body
        this.dfvAddEdit = true
        this.getKVSysModule(this.platformId)
      }
      this.editParentId = row.parentId
    },
    // 添加编辑
    async addOrMod(formName, noClose) {
      // if (!this.formModel.meta) {
      //   this.onCreateMeta()
      // }
      if (this.formOp === '添加') {
        // 添加操作
        this.$refs[formName].validate(async valid => {
          if (valid) {
            const res = await this.btnApiAuth.add.api(
              this.formModel,
              this,
              'loadingForm'
            )
            if (res.ok) {
              this.$message({ type: 'success', message: '添加成功' })
              if (!noClose) {
                this.dfvAddEdit = false
                // 刷新同一个父模块部分
                if (this.formModel.parentId) {
                  const { tree, treeNode, resolve } = this.loadNodeMap.get(
                    this.formModel.parentId
                  )
                  if (tree.id) {
                    // 移除所有子节点并重读
                    this.loadChildrenNode(tree, treeNode, resolve)
                  }
                } else {
                  this.getList()
                }
              }
            }
          } else {
            this.$notify.error({
              title: '错误',
              message: '请检查输入是否正确！',
              offset: 100
            })
            return false
          }
        })
      } else {
        // 修改操作
        this.$refs[formName].validate(async valid => {
          if (valid) {
            const res = await this.btnApiAuth.mod.api(this.formModel, this, 'loadingForm')
            if (res.ok) {
              this.$message({ type: 'success', message: '编辑成功' })
              if (!noClose) {
                this.dfvAddEdit = false
                // 改了父id需要刷新页面 防止出现不可预知的错误
                if (this.editParentId !== this.formModel.parentId) {
                  // this.$set(this.$refs.tableDom.store.states.lazyTreeNodeMap, row.id, [])
                  // this.tableData = []
                  // this.loadNodeMap.clear()
                  window.location.reload()
                  return
                }
                // 刷新同一个父模块部分
                if (this.formModel.parentId) {
                  const node = this.loadNodeMap.get(this.formModel.parentId)
                  if (node && node.tree.id) {
                    // 移除所有子节点并重读
                    this.loadChildrenNode(node.tree, node.treeNode, node.resolve)
                  }
                } else {
                  this.getList()
                }
              }
            }
          } else {
            this.$notify.error({ title: '错误', message: '请检查输入是否正确！', offset: 100 })
            return false
          }
        })
      }
    },
    // 详情
    async onView(row) {
      const param = { id: row.id }
      const res = await this.btnApiAuth.det.api(param, this, 'loading')
      if (res.ok) {
        this.formOp = '查看'
        this.formModel = res.body
        this.dfvAddEdit = true
        this.getKVSysModule(this.platformId)
      }
    },
    // 行编辑
    async onRowMod(row, cols) {
      if (this.recMode) {
        this.$message({ type: 'warning', message: '已删除数据不可编辑' })
        this.getList()
        return
      }
      for (const k in cols) {
        row[k] = cols[k]
      }
      const res = await this.btnApiAuth.mod.api(row, this, 'loading')
      if (res.ok) {
        this.$message({ message: '编辑成功', type: 'success' })
        // 刷新同一个父模块部分
        if (row.parentId) {
          const { tree, treeNode, resolve } = this.loadNodeMap.get(row.parentId)
          if (tree.id) {
            // 移除所有子节点并重读
            this.loadChildrenNode(tree, treeNode, resolve)
          }
        } else {
          this.getList(false, null, true)
        }
      }
    },
    // 多选
    onMulSelect(rows) {
      this.selectRows = rows
    },
    // 排序
    onSortTable(sort) {
      if (sort.order) {
        this.sortCol = sort.prop + ' ' + sort.order.replace('ending', '')
      } else {
        this.sortCol = ''
      }
      this.getList()
    },
    // 刷新指定行子模块 https://www.cnblogs.com/dengxiaoning/p/11681304.html
    renderChildrenNode(row, childRows) {
      if (this.loadNodeMap.has(row.id)) {
        // eslint-disable-next-line no-unused-vars
        const { tree, treeNode, resolve } = this.loadNodeMap.get(row.id)
        // 移除旧的
        this.$set(this.$refs.tableDom.store.states.lazyTreeNodeMap, row.id, [])
        resolve(childRows)
      } else {
        row['hasChildren'] = true
      }
    },
    // 读取指定行所有子节点模块数据
    async loadChildrenNode(row, treeNode, resolve) {
      // console.log(row)
      var pageParam = {
        // searchValue: this.query,
        pageIndex: 1,
        pageSize: 999999,
        orderBy: this.sortCol,
        showMode: 1,
        showPageTotal: this.showPageTotal,
        whereDynamicFilter: '',
        parentId: row.id
      }
      if (this.platformId !== 0) {
        pageParam['platformId'] = this.platformId
      }
      // if (where) {
      //   this.pageDto.whereDynamicFilter = JSON.stringify(where)
      // }
      const res = await this.btnApiAuth.pageList.api(pageParam, this)
      if (res.ok) {
        // eslint-disable-next-line require-atomic-updates
        row['hasChildren'] = res.body.list.length > 0
        // 所有加载数据时用到的数据都保存起来 后面做手动刷新
        this.$set(this.$refs.tableDom.store.states.lazyTreeNodeMap, row.id, [])
        this.loadNodeMap.delete(row.id)
        this.loadNodeMap.set(row.id, { tree: row, treeNode, resolve })
        resolve(res.body.list)
      }
    },
    // 分页列表 先读取第一层根节点
    async getList(changePage, where, useLast) {
      if (!this.btnApiAuth.pageList.result) {
        this.$message({ type: 'error', message: '您没有查看列表权限！' })
        return
      }
      if (changePage) {
        this.currPage = 1
      }
      if (!useLast) {
        this.pageDto = {
          searchValue: this.query,
          pageIndex: this.currPage,
          pageSize: this.pageSize,
          orderBy: this.sortCol,
          showMode: 1,
          showPageTotal: this.showPageTotal,
          whereDynamicFilter: '',
          parentId: 0
        }
        // 搜索和回收站情况下不限制父id
        if (this.query || this.recMode) {
          delete this.pageDto.parentId
        }
        if (this.platformId !== 0) {
          this.pageDto['platformId'] = this.platformId
        }
        if (where) {
          this.pageDto.whereDynamicFilter = JSON.stringify(where)
        }
      }
      if (this.recMode) {
        this.pageDto.showMode = 3
      } else {
        this.pageDto.showMode = 1
      }
      const res = await this.btnApiAuth.pageList.api(this.pageDto, this, 'loading')
      if (res.ok) {
        this.tableData = res.body.list
        this.pageSize = res.body.pageSize
        this.pageTotal = res.body.total
      }
    },
    // 高级过滤
    onSearchFilter(dynamicFilter) {
      this.getList(true, dynamicFilter)
      this.searchWindowVisible = false
    },
    // 表格编辑相关
    onCellEdit(row, column) {
      if (this.canShowBtn('mod')) {
        this.cellId = row.id
        this.cellKey = column.property
        this.cellVal = row[column.property]
      }
    },
    onCellCancel(row, column) {
      if (
        row &&
        row.id === this.cellId &&
        column &&
        column.property === this.cellKey
      ) {
        return
      }
      this.cellId = 0
      this.cellKey = null
      this.cellVal = null
    },
    onCellMod(row) {
      if (row) {
        const col = {}
        col[this.cellKey] = this.cellVal
        this.onRowMod(row, col)
      }
      this.onCellCancel()
    },
    // 分页相关
    onPageSizeChange(pageSize) {
      this.pageSize = pageSize
      this.getList()
    },
    onCurrPageChange(pageIndex) {
      this.currPage = pageIndex
      this.getList()
    },
    // 弹窗关闭
    onFormClose(diaName) {
      this.$refs[diaName].resetFields()
    },
    // 鉴权
    canShowBtn(apiKey) {
      var baa = this.btnApiAuth[apiKey]
      if (!baa) {
        return false
      }
      if (!baa.result) {
        return false
      }
      if (this.recMode && !baa.recShow) {
        return false
      }
      if (!this.recMode && !baa.norShow) {
        return false
      }
      return true
    }
  }
}
</script>

<style lang="scss">
</style>

